from django.db import models
from utils.models import CoreModel, BaseModel, table_prefix
from mysystem.models import Users


class DatabaseConfig(CoreModel):
    """
    数据库配置表
    用于存储第三方数据库的连接信息，支持动态配置和切换
    """
    # 新增：数据库类型字段（与引擎对应，更直观区分数据库类型）
    DB_TYPE_CHOICES = [
        ('MySQL', 'MySQL'),
        ('PostgreSQL', 'PostgreSQL'),
        ('SQLite', 'SQLite'),
        ('Oracle', 'Oracle'),
        ('SQL Server', 'SQL Server'),
    ]
    db_type = models.CharField(
        max_length=20,
        choices=DB_TYPE_CHOICES,
        default='mysql',
        verbose_name="数据库类型",
        help_text="直观区分数据库类型（如MySQL、SQL Server）"
    )

    # 新增：所属机构相关字段
    organ_id = models.CharField(
        max_length=100,
        verbose_name="所属机构ID",
        help_text="该数据库配置所属机构的唯一标识ID"
    )
    organ_name = models.CharField(
        max_length=200,
        verbose_name="所属机构名称",
        help_text="该数据库配置所属机构的名称"
    )

    # 数据库别名（唯一标识）
    db_alias = models.CharField(
        max_length=50,
        unique=True,
        verbose_name="数据库别名",
        help_text="用于标识数据库的唯一名称，如 'user_center'"
    )

    # 数据库引擎（完整路径）
    ENGINE_CHOICES = [
        ('django.db.backends.mysql', 'django.db.backends.mysql'),
        ('django.db.backends.postgresql', 'django.db.backends.postgresql'),
        ('django.db.backends.sqlite3', 'django.db.backends.sqlite3'),
        ('django.db.backends.oracle', 'django.db.backends.oracle'),
        ('sql_server.pyodbc', 'sql_server.pyodbc'),
    ]
    engine = models.CharField(
        max_length=100,
        choices=ENGINE_CHOICES,
        default='django.db.backends.mysql',
        verbose_name="数据库引擎",
        help_text="数据库类型对应的引擎路径"
    )

    # 数据库连接基本信息
    db_name = models.CharField(max_length=100, verbose_name="数据库名称")
    host = models.CharField(max_length=100, verbose_name="主机地址")
    port = models.CharField(
        max_length=20,
        default="",
        blank=True,
        verbose_name="端口号",
        help_text="留空使用默认端口"
    )
    user = models.CharField(max_length=50, verbose_name="登录用户名")
    password = models.CharField(max_length=100, verbose_name="登录密码")

    # 额外连接参数（JSON格式，默认空字典）
    options = models.JSONField(
        default=dict,  # 默认空字典
        blank=True,
        verbose_name="额外连接参数",
        help_text="仅包含数据库驱动支持的参数（如SQL Server的driver）"
    )

    # 事务配置（默认开启）
    atomic_requests = models.BooleanField(
        default=True,  # 默认为True
        verbose_name="是否开启请求事务",
        help_text="每个请求自动包裹事务（True/False）"
    )

    # 连接健康检查（默认关闭）
    conn_health_checks = models.BooleanField(
        default=False,  # 新增字段，默认为False
        verbose_name="是否启用连接健康检查",
        help_text="获取连接时自动检测有效性（True/False）"
    )

    # 连接最大存活时间（秒，默认30）
    conn_max_age = models.PositiveIntegerField(
        default=30,  # 新增字段，默认为30秒
        verbose_name="连接最大存活时间",
        help_text="连接可复用的最长时间（秒），0表示不复用"
    )

    # 自动提交事务（默认开启）
    autocommit = models.BooleanField(
        default=True,  # 新增字段，默认为True
        verbose_name="是否自动提交事务",
        help_text="操作后是否自动提交事务（True/False）"
    )

    # 时区字段（业务逻辑用，不参与数据库连接）
    time_zone = models.CharField(
        max_length=100,
        blank=True,
        null=True,
        verbose_name="数据库时区（业务用）",
        help_text="用于业务逻辑中的时区转换（如'Asia/Shanghai'），不影响数据库连接",
        default="Asia/Shanghai"
    )

    # 状态控制
    is_active = models.BooleanField(
        default=True,
        verbose_name="是否启用",
        help_text="关闭后无法通过该配置连接数据库"
    )
    remark = models.CharField(
        max_length=500,
        blank=True,
        null=True,
        verbose_name="备注信息"
    )

    class Meta:
        verbose_name = "数据库配置"
        verbose_name_plural = "数据库配置"
        db_table = "sys_database_config"
        ordering = ["create_datetime"]
        # 可根据需要添加机构相关的索引，优化查询
        indexes = [
            models.Index(fields=["organ_id"], name="idx_organ_id"),
        ]

    def __str__(self):
        return f"{self.db_alias}（{self.get_db_type_display()} - {self.organ_name}）"

    def get_default_port(self):
        """根据引擎返回默认端口"""
        engine_port_map = {
            'django.db.backends.mysql': '3306',
            'django.db.backends.postgresql': '5432',
            'django.db.backends.oracle': '1521',
            'mssql.backends.mssql': '1433',
        }
        return engine_port_map.get(self.engine, '')

    @property
    def full_connection_info(self):
        """返回完整的数据库连接配置"""
        config = {
            "ENGINE": self.engine,
            "NAME": self.db_name,
            "USER": self.user,
            "PASSWORD": self.password,
            "HOST": self.host,
            "PORT": self.port or self.get_default_port(),
            "OPTIONS": self.options,
            "ATOMIC_REQUESTS": self.atomic_requests,
            "CONN_HEALTH_CHECKS": self.conn_health_checks,  # 新增参数
            "CONN_MAX_AGE": self.conn_max_age,  # 新增参数
            "AUTOCOMMIT": self.autocommit,  # 新增参数
        }

        # SQLite特殊处理
        if self.engine == 'django.db.backends.sqlite3':
            config.pop("HOST")
            config.pop("PORT")

        return config

    @property
    def business_timezone(self):
        """提供业务逻辑中使用的时区信息"""
        return self.time_zone or "UTC"